package com.wanwu.channel.notify.process;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.wanwu.channel.common.enums.*;
import com.wanwu.channel.common.util.DateUtils;
import com.wanwu.channel.common.util.LogUtil;
import com.wanwu.channel.core.ChannelPayService;
import com.wanwu.channel.core.tool.AlarmPoolUtil;
import com.wanwu.channel.dao.entity.ChannelApplyClearanceEntity;
import com.wanwu.channel.dao.entity.ChannelPayEntity;
import com.wanwu.monitor.api.util.vo.AlarmMsgVo;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.Date;
import java.util.TreeMap;

@Component
public class TongLianNotifyProcess {

    private static final Logger logger = LoggerFactory.getLogger(TongLianNotifyProcess.class);


    @Resource
    private BusinessNotifyProcess businessNotifyProcess;

    @Resource
    private ChannelPayService channelPayService;

    @Resource
    private AlarmPoolUtil alarmPoolUtil;

    /**
     * 通联回调处理：
     * 1.判断订单是否存在
     * 2.判断订单是否为终态，为终态时判断与通联回调状态是否一致，不一致时报警，返回通联回调成功，不再重发
     * 3.判断回调的总金额是否和数据库一致，不一致时报警，返回通联成功，不再重发
     * 4.处理回调结果，更新本地库
     * 5.回调支付系统
     *
     * @param params  回调入参
     * @param dingKey 报警的钉钉key
     */
    public void tongLianNotify(TreeMap<String, String> params, String bizCode, String dingKey, int thirdFlag) {

        //查询订单是否存在
        ChannelPayEntity channelPayEntity = null;
        if(0 == thirdFlag){
            channelPayEntity = channelPayService.queryByBizOrderNoFMaster(params.get("cusorderid"), bizCode);
        }else {
            channelPayEntity = channelPayService.queryByChannelNoFMaster(params.get("cusorderid"));
        }
        if (ObjectUtils.isEmpty(channelPayEntity)) {
            //DingUtil.sendDingAtPeople(dingKey, "通联回调订单不存在", JSON.toJSONString(params), null);
            alarmPoolUtil.addCommonAlarm(dingKey, AlarmTypeEnum.TLNOTIFYORDERNOTEXIST, "渠道系统告警：通联回调订单不存在\n\n" + JSON.toJSONString(params));
            return;
        }
        //判断订单是否为终态，为终态时判断与通联回调状态是否一致，不一致时报警，返回通联回调成功，不再重发
        String trxstatus = params.get("trxstatus");
        //转成本地状态枚举
        Integer notifyStatus = "0000".equals(trxstatus) ? ChannelPayStatus.SUCCESS.getValue() : ChannelPayStatus.FAIL.getValue();
        //终态不做任何更新
        if (!ChannelPayStatus.PROCESSING.getValue().equals(channelPayEntity.getPayStatus())) {
            if (!notifyStatus.equals(channelPayEntity.getPayStatus())) {
                //报警通知稍后再加
                //String msg = "渠道单号：" + channelPayEntity.getChannelNo() + "\n\n本地状态：" + channelPayEntity.getPayStatus() + "\n\n回调状态：" + notifyStatus;
                //DingUtil.sendDingAtPeople(dingKey, "通联回调状态与本地不一致", msg, null);
                AlarmMsgVo alarmMsgVo = new AlarmMsgVo.Builder().head("渠道系统告警：通联回调状态与本地不一致")
                        .field("渠道单号", channelPayEntity.getChannelNo())
                        .field("本地状态", channelPayEntity.getPayStatus())
                        .field("回调状态", notifyStatus).build();
                alarmPoolUtil.addGatherAlarm(dingKey, AlarmTypeEnum.TLNOTIFYSTATUSDIFF, alarmMsgVo);
            }
            return;
        }
        //判断通知报文中总金额跟数据库是否一致，不一致报警
        int totalFee = Integer.parseInt(params.get("trxamt"));
        if (totalFee != channelPayEntity.getRmbAmount()) {
            //报警通知稍后再加
            //String msg = "渠道单号：" + channelPayEntity.getChannelNo() + "\n\n本地支付金额：" + channelPayEntity.getRmbAmount() + "\n\n回调支付金额：" + totalFee;
            //DingUtil.sendDingAtPeople(dingKey, "通联支付回调订单金额与本地不一致", msg, null);
            AlarmMsgVo alarmMsgVo = new AlarmMsgVo.Builder().head("渠道系统告警：通联支付回调订单金额与本地不一致")
                    .field("渠道单号", channelPayEntity.getChannelNo())
                    .field("本地支付金额", String.valueOf(channelPayEntity.getRmbAmount()))
                    .field("回调支付金额", totalFee).build();
            alarmPoolUtil.addGatherAlarm(dingKey, AlarmTypeEnum.TLPAYNOTIFYAMOUNTDIFF, alarmMsgVo);
            return;
        }
        //处理回调结果
        channelPayEntity.setThirdOrderNo(params.get("chnltrxid"));
        channelPayEntity.setTradeStatus(trxstatus);
        channelPayEntity.setNotifyData(JSON.toJSONString(params));
        channelPayEntity.setPayStatus(notifyStatus);
        if (ChannelPayStatus.SUCCESS.getValue().equals(notifyStatus)) {
            //成功处理
            channelPayEntity.setPayTime(DateUtils.formatDate(8, params.get("paytime")));
            //海关总署-通联H5支付方式返回报文，落的是查询或者回调报文终态
            if (PayType.ALLIAN_H5.check(channelPayEntity.getPayType())) {
                channelPayEntity.setPrepayReturnData(JSON.toJSONString(params));
            }
        } else {
            //失败处理
            channelPayEntity.setErrorCode(trxstatus);
            //错误信息回调的时候未返回，目前存不了
            //channelPayEntity.setErrorMsg(params.get("err_code_des"));
        }
        channelPayEntity.setNotifyNum(channelPayEntity.getNotifyNum() + 1);
        channelPayEntity.setUpdateTime(new Date());
        channelPayEntity = channelPayService.checkAndUpdateByChannelNo(channelPayEntity);
        //回调支付系统
        if (!StringUtils.isEmpty(channelPayEntity.getNotifyData())) {
            businessNotifyProcess.notifyToBusinessLine(channelPayEntity);
        }
    }


    /**
     * 转换回执码值和说明
     *
     * @param returnStatus
     * @return
     */
    private TlQryResultEnum convertCustomsResult(String returnStatus) {
        switch (returnStatus) {
            case "120":
                return TlQryResultEnum.DECLARE_SUCCESS;
            case "2":
                return TlQryResultEnum.TL_INSERT_SUCCESS;
            case "3":
                return TlQryResultEnum.ALREADY_DECLARE;
            case "4":
                return TlQryResultEnum.DECLARE_FAIL;
            case "100":
                return TlQryResultEnum.CUSTOMS_REJECT;
            default:
                return TlQryResultEnum.DEAL_ERROR;
        }
    }

    /**
     * 转换通联回调状态为本地
     *
     * @param returnStatus
     * @return
     */
    private Integer convertStatus(String returnStatus) {
        if ("120".equals(returnStatus)) {
            //海关入库，申报成功
            return ChannelClearanceStatus.SUCCESS.getValue();
        } else if ("2".equals(returnStatus) || "3".equals(returnStatus)) {
            //电子口岸申报中和发送海关成功视为处理中
            return ChannelClearanceStatus.PROCESSING.getValue();
        } else if ("100".equals(returnStatus)) {
            //海关退单,发送海关失败，属于申报失败,需要人工处理
            return ChannelClearanceStatus.REJECT.getValue();
        } else {
            //发送海关失败，属于申报失败
            return ChannelClearanceStatus.FAIL.getValue();
        }
    }
}
